// #include <iostream>
// #include <unistd.h>
// #include <cassert>
// #include<cstring>
// #include <sys/types.h>
// #include <sys/wait.h>

// #define MAX 1024
// using namespace std;

// int main()
// {
//     // 1.先建立管道
//     int pipefd[2] = {0};
//     int n = pipe(pipefd);
//     assert(n == 0);
//     (void)n; //
//     std::cout << "pipefd[0]:" << pipefd[0] << ","
//               << "pipefd[1]:" << pipefd[1] << std::endl;

//     // 第2步，创建子进程
//     pid_t id = fork();
//     if (id < 0)
//     {
//         perror("fork");
//         return -1;
//     }
//     // 第3步，父子关闭不需要的fd，形成单向通信的管道
//     // 子写父读
//     if (id == 0) // child
//     {
//         close(pipefd[0]);
//         char message[MAX];
//         int cnt = 10;
//         while (cnt)
//         {
//             snprintf(message, sizeof(message), "Hello father, I am child, pid: %d,cnt: %d\n", getpid(), cnt);
//             write(pipefd[1], message, strlen(message));
//             cnt--;
//             sleep(1);
//         }
//         exit(0);
//     }
//     // father

//     close(pipefd[1]);
//     char buffer[MAX];

//     while (true)
//     {
//         int n = read(pipefd[0], buffer, sizeof(buffer) - 1);
//         if(n > 0)
//         {
//             buffer[n] = '\0';
//             cout << getpid() << "child say: " << buffer << endl;
//         }
//     }

//     pid_t rid = waitpid(id, nullptr, 0);
//     if (rid == id)
//     {
//         cout << "wait success!" << endl;
//     }
//     else
//     {
//         cout << "wait nosucess!" << endl;
//     }
//     return 0;
// }

//管道的四种情况

//管道的五种特性


//情况1和特性2,3验证：
#include <iostream>
#include <unistd.h>
#include <cassert>
#include<cstring>
#include <sys/types.h>
#include <sys/wait.h>

#define MAX 1024
using namespace std;

int main()
{
    // 1.先建立管道
    int pipefd[2] = {0};
    int n = pipe(pipefd);
    assert(n == 0);
    (void)n; //
    std::cout << "pipefd[0]:" << pipefd[0] << ","
              << "pipefd[1]:" << pipefd[1] << std::endl;

    // 第2步，创建子进程
    pid_t id = fork();
    if (id < 0)
    {
        perror("fork");
        return -1;
    }
    // 第3步，父子关闭不需要的fd，形成单向通信的管道
    // 子写父读
    if (id == 0) // child
    {
        close(pipefd[0]);
        char message[MAX];
        int cnt = 1000;
        while (true)
        {
            snprintf(message, sizeof(message), "Hello father, I am child, pid: %d,cnt: %d\n", getpid(), cnt);
            write(pipefd[1], message, strlen(message));
            cnt--;
            //sleep(100);写入更慢，读入更快
            cout << "write..." << endl;
        }
        exit(0);
    }
    // father

    close(pipefd[1]);
    char buffer[MAX];

    while (true)
    {
        //sleep(2);写入更快，读入更慢
        ssize_t n = read(pipefd[0], buffer, sizeof(buffer) - 1);
        if(n > 0)
        {
            buffer[n] = '\0';
            cout << getpid() << "child say: " << buffer << endl;
        }
    }

    pid_t rid = waitpid(id, nullptr, 0);
    if (rid == id)
    {
        cout << "wait success!" << endl;
    }
    else
    {
        cout << "wait nosucess!" << endl;
    }
    return 0;
}